/**
 * 
 */
package com.ccqlk.attendance.controller.manage;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ccqlk.attendance.common.page.Direction;
import com.ccqlk.attendance.common.page.PageRequest;
import com.ccqlk.attendance.common.page.Sort;
import com.ccqlk.attendance.repository.service.base.BaseService;
import com.ccqlk.common.jquery.jqgrid.JqGrid;
import com.ccqlk.utils.RequestUtil;
import com.github.pagehelper.PageInfo;

/**
 * Copyright 2015-2018 重庆鲁控科技有限公司<br>
 * 文件标题: AbstractManageController<br>
 * 文件说明: TODO<br>
 * @author ZhangYinxian 348893009@qq.com<br>
 * 创建时间 2016年5月27日 上午9:04:33<br>
 */
public abstract class AbstractManageController<T, ID> implements BaseController<T, ID> {

	private Logger logger = LoggerFactory.getLogger(AbstractManageController.class);
	
	protected String baseTemplateUrl = "";
	protected String listUrl = "redirect:list.jspx";
	protected String entityName = "entity";
	
	private BaseService<T, ID> baseService;
	
	public AbstractManageController(BaseService<T, ID> baseService) {
		this.baseService = baseService;
	}
	
	public AbstractManageController(BaseService<T, ID> baseService, String baseTemplateUrl, String entityName){
		this(baseService);
		this.baseTemplateUrl = baseTemplateUrl;
		this.entityName = entityName;
	}
	
	public void preAddHanle(HttpServletRequest request, Model model){}
	/* (non-Javadoc)
	 * @see com.ccqlk.attendance.controller.manage.BaseController#preAdd(javax.servlet.http.HttpServletRequest, org.springframework.ui.Model)
	 */
	@Override
	@RequestMapping("preAdd")
	public String preAdd(HttpServletRequest request, Model model) {
		preAddHanle(request, model);
		return baseTemplateUrl + "preAdd";
	}
	
	@RequestMapping("preAddJson")
	@ResponseBody
	public Model preAddJson(HttpServletRequest request, Model model){
		preAddHanle(request, model);
		return renderSuccess(request, model, "success");
	}

	public void addHandle(HttpServletRequest request, T entity, BindingResult result){}
	
	@RequestMapping("addJson")
	@ResponseBody
	public Model addJson(HttpServletRequest request, T entity, Model model, BindingResult result){
		if (logger.isDebugEnabled()) {
			logger.debug("add binding result, hasError:{}, errorCount:{}", result.hasErrors(), result.getErrorCount());
		}
		addHandle(request, entity, result);
		if (result!=null && result.hasErrors()) {
			List<ObjectError> erros = result.getAllErrors();
			StringBuilder errorBuilder = new StringBuilder();
			for (ObjectError objectError : erros) {
				errorBuilder.append("errorCode:");
				errorBuilder.append(objectError.getCode());
				errorBuilder.append(" errorMessage:");
				errorBuilder.append(objectError.getDefaultMessage());
				errorBuilder.append(";\r\n");
			}
			
			return renderFail(request, model, errorBuilder.toString());
		}
		int count = baseService.add(entity);
		
		if (count>0) {
			return renderSuccess(request, model, "添加成功");
		}
		return renderFail(request, model, "添加失败");
	}

	/* (non-Javadoc)
	 * @see com.ccqlk.attendance.controller.manage.BaseController#add(javax.servlet.http.HttpServletRequest, java.lang.Object, org.springframework.validation.BindingResult)
	 */
	@Override
	@RequestMapping("add")
	public String add(HttpServletRequest request, T entity, BindingResult result) {
		if (logger.isDebugEnabled()) {
			logger.debug("add binding result, hasError:{}, errorCount:{}", result.hasErrors(), result.getErrorCount());
		}
		addHandle(request, entity, result);
		if (entity!=null) {
			baseService.add(entity);
		}
		return listUrl;
	}

	public void preEditHandle(HttpServletRequest request, T entity, Model model){}
	
	@RequestMapping("preEditJson")
	@ResponseBody
	public Model preEditJson(HttpServletRequest request, @RequestParam(value="id", defaultValue="-1")ID key, Model model){
		T entity = baseService.selectByPrimaryKey(key);
		if (entity==null) {
			return renderFail(request, model, "获取对象失败");
		}
		preEditHandle(request, entity, model);
		model.addAttribute(entityName, entity);
		return renderSuccess(request, model, "获取对象成功");
	}
	
	/* (non-Javadoc)
	 * @see com.ccqlk.attendance.controller.manage.BaseController#preEdit(javax.servlet.http.HttpServletRequest, java.lang.Object, org.springframework.ui.Model)
	 */
	@Override
	@RequestMapping("preEdit")
	public String preEdit(HttpServletRequest request, @RequestParam(value="id", defaultValue="-1")ID key, Model model) {
		T entity = baseService.selectByPrimaryKey(key);
		preEditHandle(request, entity, model);
		model.addAttribute(entityName, entity);
		
		return baseTemplateUrl + "preEdit";
	}

	public void editHandle(HttpServletRequest request, T entity, BindingResult result){}
	
	@RequestMapping("editJson")
	@ResponseBody
	public Model editJson(HttpServletRequest request, T entity, Model model, BindingResult result){
		editHandle(request, entity, result);
		if (entity==null || (result!=null && result.hasErrors())) {
			List<ObjectError> erros = result.getAllErrors();
			StringBuilder errorBuilder = new StringBuilder();
			for (ObjectError objectError : erros) {
				errorBuilder.append("errorCode:");
				errorBuilder.append(objectError.getCode());
				errorBuilder.append(" errorMessage:");
				errorBuilder.append(objectError.getDefaultMessage());
				errorBuilder.append(";\r\n");
			}
			
			return renderFail(request, model, errorBuilder.toString());
		}
		
		int count = baseService.edit(entity);
		if (count==0) {
			return renderFail(request, model, "修改对象失败");
		}
		return renderSuccess(request, model, "修改对象成功");
	}
	/* (non-Javadoc)
	 * @see com.ccqlk.attendance.controller.manage.BaseController#edit(javax.servlet.http.HttpServletRequest, java.lang.Object, org.springframework.validation.BindingResult)
	 */
	@Override
	@RequestMapping("edit")
	public String edit(HttpServletRequest request, T entity, BindingResult result) {
		if (logger.isDebugEnabled()) {
			logger.debug("edit binding result, hasError:{}, errorCount:{}", result.hasErrors(), result.getErrorCount());
		}
		editHandle(request, entity, result);
		baseService.edit(entity);
		return listUrl;
	}

	@RequestMapping("deleteJson")
	@ResponseBody
	public Model deleteJson(HttpServletRequest request, @RequestParam(value="id", defaultValue="-1")ID key, Model model){
		int count = baseService.delete(key);
		if (count==0) {
			return renderFail(request, model, "删除失败");
		}
		
		return renderSuccess(request, model, "删除成功");
	}
	/* (non-Javadoc)
	 * @see com.ccqlk.attendance.controller.manage.BaseController#delete(javax.servlet.http.HttpServletRequest, java.lang.Object)
	 */
	@Override
	@RequestMapping("delete")
	public String delete(HttpServletRequest request, @RequestParam(value="id", defaultValue="-1")ID key) throws Exception {
		int count = baseService.delete(key);
		if (count==0) {
			throw new Exception("删除失败");
		}
		return listUrl;
	}

	public void listHandle(HttpServletRequest request){}
	/* (non-Javadoc)
	 * @see com.ccqlk.attendance.controller.manage.BaseController#list(javax.servlet.http.HttpServletRequest)
	 */
	@Override
	@RequestMapping("list")
	public String list(HttpServletRequest request) {
		listHandle(request);
		return baseTemplateUrl + "list";
	}

	/* (non-Javadoc)
	 * @see com.ccqlk.attendance.controller.manage.BaseController#getJson(javax.servlet.http.HttpServletRequest, org.springframework.ui.Model)
	 */
	@Override
	@RequestMapping("getJson")
	@ResponseBody
	public Model getJson(HttpServletRequest request, Model model) {
		
        boolean pageable = RequestUtil.getPageable(request);
		
		JqGrid<T> jqGrid = new JqGrid<>(request, model);
		PageRequest pageRequest = getPageRequest(jqGrid, request);
		PageInfo<T> pageData = getData(pageRequest, request, model,pageable);
		if(pageData!=null){
			jqGrid.setDatarows(pageData.getList());
			jqGrid.setRecords(pageData.getTotal());
		}
		jqGrid.flush();
		
		return model;
	}

	/**
	 * 根据具体业务填充数据
	 * @param pageRequest 页面请求信息
	 * @param request request请求
	 * @param model 页面模型对象
	 * @param pageable 标记是否需要分页，false不分页，true分页
	 * @return pageInfo 分页对象
	 */
	public abstract PageInfo<T> getData(PageRequest pageRequest, HttpServletRequest request, Model model, boolean pageable);
	

	/**
	 * 获取分页信息对象
	 * @param jqGrid 按照jqGrid封装的对象
	 * @param request http请求
	 * @return 分页信息对象
	 */
	private PageRequest getPageRequest(JqGrid<T> jqGrid, HttpServletRequest request) {
		PageRequest pageRequest = null;
		int page = jqGrid.getPage();
		int size = jqGrid.getRows();
		Sort sort = getSort(request);
		if(sort!=null){
			pageRequest = new PageRequest(page, size, sort);
		}else{
			pageRequest = new PageRequest(page, size);
		}
		return pageRequest;
	}

	/** 获取排序信息，按照jqGrid排序要求获取
	 * @param request http请求
	 * @return 排序信息
	 */
	public Sort getSort(HttpServletRequest request) {
		String sortString = RequestUtil.getValueByName(request, "sidx","");
		String sortType = RequestUtil.getValueByName(request, "sord", "asc");
		if(!"".equals(sortString)){
			Direction direction = Direction.parse(sortType);
			Sort sort = new Sort(direction, sortString);
			return sort;
		}else{
			return null;
		}
	}

	public Model render(HttpServletRequest request, Model model, int status, String message){
		model.addAttribute("status", status);
		model.addAttribute("message", message);
		return model;
	}
	
	public Model renderSuccess(HttpServletRequest request, Model model, String message){
		return render(request, model, 1, message);
	}
	
	public Model renderFail(HttpServletRequest request, Model model, String message){
		return render(request, model, 0, message);
	}
	
}
